package cn.iocoder.lw.module.core.controller.app.house;

import cn.iocoder.lw.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.lw.framework.common.pojo.CommonResult;
import cn.iocoder.lw.framework.common.pojo.PageResult;
import cn.iocoder.lw.framework.common.util.object.BeanUtils;
import cn.iocoder.lw.framework.excel.core.util.ExcelUtils;
import cn.iocoder.lw.module.core.controller.admin.house.vo.*;
import cn.iocoder.lw.module.core.convert.house.CoreHouseConvert;
import cn.iocoder.lw.module.core.dal.dataobject.house.CoreHouseDO;
import cn.iocoder.lw.module.core.service.house.CoreHouseService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

import static cn.iocoder.lw.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.lw.framework.common.pojo.CommonResult.success;

@Tag(name = "用户 APP - 核心房源")
@RestController
@RequestMapping("/core/house")
@Validated
public class AppCoreHouseController {

    @Resource
    private CoreHouseService houseService;

    @PostMapping("/create")
    @Operation(summary = "创建房源")
    @PreAuthorize("@ss.hasPermission('core:house:create')")
    @ApiAccessLog(operateType = CREATE)
    public CommonResult<Long> createHouse(@Valid @RequestBody CoreHouseSaveReqVO createReqVO) {
        return success(houseService.createHouse(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新房源")
    @PreAuthorize("@ss.hasPermission('core:house:update')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> updateHouse(@Valid @RequestBody CoreHouseSaveReqVO updateReqVO) {
        houseService.updateHouse(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除房源")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('core:house:delete')")
    @ApiAccessLog(operateType = DELETE)
    public CommonResult<Boolean> deleteHouse(@RequestParam("id") Long id) {
        houseService.deleteHouse(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得房源")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('core:house:query')")
    public CommonResult<CoreHouseRespVO> getHouse(@RequestParam("id") Long id) {
        return success(BeanUtils.toBean(houseService.getHouse(id), CoreHouseRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得房源分页")
    @PreAuthorize("@ss.hasPermission('core:house:query')")
    public CommonResult<PageResult<CoreHouseRespVO>> getHousePage(@Valid CoreHousePageReqVO pageReqVO) {
        PageResult<CoreHouseRespVO> pageResult = houseService.getHousePage(pageReqVO);
        return success(pageResult);
    }

    @GetMapping("/project/{projectId}")
    @Operation(summary = "根据项目编号获取房源列表")
    @Parameter(name = "projectId", description = "项目编号", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('core:house:query')")
    public CommonResult<List<CoreHouseRespVO>> getHouseListByProjectId(@PathVariable("projectId") Long projectId) {
        return success(houseService.getHouseListByProjectId(projectId));
    }

    @GetMapping("/my")
    @Operation(summary = "获得我负责的房源列表")
    @PreAuthorize("@ss.hasPermission('core:house:query')")
    public CommonResult<PageResult<CoreHouseRespVO>> getMyHousePage(@Valid CoreHousePageReqVO pageReqVO) {
        PageResult<CoreHouseRespVO> pageResult = houseService.getHousePage(pageReqVO);
        return success(pageResult);
    }

    @GetMapping("/available/{projectId}")
    @Operation(summary = "获取项目下的可用房源列表")
    @Parameter(name = "projectId", description = "项目编号", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('core:house:query')")
    public CommonResult<List<CoreHouseRespVO>> getAvailableHouseListByProjectId(@PathVariable("projectId") Long projectId) {
        CoreHousePageReqVO reqVO = new CoreHousePageReqVO();
        reqVO.setProjectId(projectId);
        reqVO.setStatus(0); // 0-可用
        reqVO.setPageSize(1000);
        PageResult<CoreHouseRespVO> pageResult = houseService.getHousePage(reqVO);
        return success(pageResult.getList());
    }

    @GetMapping("/count-by-project")
    @Operation(summary = "根据项目编号和房源状态统计房源数量")
    @Parameter(name = "projectId", description = "项目编号", required = true, example = "1")
    @Parameter(name = "status", description = "房源状态", required = true, example = "0")
    @PreAuthorize("@ss.hasPermission('core:house:query')")
    public CommonResult<Long> countByProjectIdAndStatus(@RequestParam("projectId") Long projectId,
                                                         @RequestParam("status") Integer status) {
        return success(houseService.countByProjectIdAndStatus(projectId, status));
    }

    @GetMapping("/by-water-meter")
    @Operation(summary = "根据水表编号获取房源")
    @Parameter(name = "waterMeterNumber", description = "水表编号", required = true, example = "W20230001")
    @PreAuthorize("@ss.hasPermission('core:house:query')")
    public CommonResult<CoreHouseRespVO> getHouseByWaterMeterNumber(@RequestParam("waterMeterNumber") String waterMeterNumber) {
        return success(BeanUtils.toBean(houseService.getHouseByWaterMeterNumber(waterMeterNumber), CoreHouseRespVO.class));
    }

    @GetMapping("/by-electricity-meter")
    @Operation(summary = "根据电表编号获取房源")
    @Parameter(name = "electricityMeterNumber", description = "电表编号", required = true, example = "E20230001")
    @PreAuthorize("@ss.hasPermission('core:house:query')")
    public CommonResult<CoreHouseRespVO> getHouseByElectricityMeterNumber(@RequestParam("electricityMeterNumber") String electricityMeterNumber) {
        return success(BeanUtils.toBean(houseService.getHouseByElectricityMeterNumber(electricityMeterNumber), CoreHouseRespVO.class));
    }

    @GetMapping("/by-lock")
    @Operation(summary = "根据门锁编号获取房源")
    @Parameter(name = "lockNumber", description = "门锁编号", required = true, example = "L20230001")
    @PreAuthorize("@ss.hasPermission('core:house:query')")
    public CommonResult<CoreHouseRespVO> getHouseByLockNumber(@RequestParam("lockNumber") String lockNumber) {
        return success(BeanUtils.toBean(houseService.getHouseByLockNumber(lockNumber), CoreHouseRespVO.class));
    }

    @GetMapping("/by-building-floor")
    @Operation(summary = "根据楼栋和楼层获取房源列表")
    @Parameter(name = "building", description = "楼栋", required = true, example = "1号楼")
    @Parameter(name = "floor", description = "楼层", required = true, example = "5层")
    @PreAuthorize("@ss.hasPermission('core:house:query')")
    public CommonResult<List<CoreHouseRespVO>> getHouseListByBuildingAndFloor(@RequestParam("building") String building,
                                                                                          @RequestParam("floor") String floor) {
        return success(houseService.getHouseListByBuildingAndFloor(building, floor));
    }

    @GetMapping("/get-import-template")
    @Operation(summary = "下载房源导入模板")
    @PreAuthorize("@ss.hasPermission('core:house:import')")
    public void downloadImportTemplate(HttpServletResponse response) throws IOException {
        // 生成模板数据
        List<CoreHouseImportExcelVO> templateData = List.of(
                createTemplateRow("示例项目", "阳光花园", "1号楼", "5层", "501", "116.397128", "39.916527",
                        "W20230001", "E20230001", "L20230001", 1, new BigDecimal("95.50"), 0,
                        new BigDecimal("3500.00"), "精装修三居室", "张先生", "13800138000", "备注信息")
        );

        // 导出模板
        ExcelUtils.write(response, "房源导入模板.xls", "房源导入模板", CoreHouseImportExcelVO.class, templateData);
    }

    @PostMapping("/import")
    @Operation(summary = "导入房源数据")
    @PreAuthorize("@ss.hasPermission('core:house:import')")
    @ApiAccessLog(operateType = CREATE)
    public CommonResult<CoreHouseImportRespVO> importHouseList(@RequestParam("file") MultipartFile file) throws Exception {
        List<CoreHouseImportExcelVO> importData = ExcelUtils.read(file, CoreHouseImportExcelVO.class);
        return success(houseService.importHouseList(importData));
    }

    /**
     * 创建模板数据行
     */
    private CoreHouseImportExcelVO createTemplateRow(String projectName, String communityName, String building, String floor,
                                                     String roomNumber, String longitude, String latitude, String waterMeterNumber,
                                                     String electricityMeterNumber, String lockNumber, Integer houseType,
                                                     BigDecimal area, Integer status, BigDecimal rent, String description,
                                                     String contactName, String contactPhone, String remark) {
        CoreHouseImportExcelVO templateRow = new CoreHouseImportExcelVO();
        // 注意：这里使用项目名称作为示例，实际导入时需要项目ID
        templateRow.setProjectId(1L); // 模板中使用示例项目ID
        templateRow.setCommunityName(communityName);
        templateRow.setBuilding(building);
        templateRow.setFloor(floor);
        templateRow.setRoomNumber(roomNumber);
        templateRow.setLongitude(new BigDecimal(longitude));
        templateRow.setLatitude(new BigDecimal(latitude));
        templateRow.setWaterMeterNumber(waterMeterNumber);
        templateRow.setElectricityMeterNumber(electricityMeterNumber);
        templateRow.setLockNumber(lockNumber);
        templateRow.setHouseType(houseType);
        templateRow.setArea(area);
        templateRow.setStatus(status);
        templateRow.setRent(rent);
        templateRow.setDescription(description);
        templateRow.setContactName(contactName);
        templateRow.setContactPhone(contactPhone);
        templateRow.setRemark(remark);
        return templateRow;
    }

}